package com.ep.thirdPlatformProject.dhg.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ep.thirdPlatformProject.dhg.entity.DhgDepartmentEntity;
import com.ep.thirdPlatformProject.dhg.entity.vo.DhgDepartmentVO;
import com.ep.thirdPlatformProject.dhg.mapper.DhgDepartmentMapper;
import com.ep.thirdPlatformProject.dhg.mapstruct.DhgDepartmentConvertMapper;
import com.ep.thirdPlatformProject.dhg.service.DhgDepartmentService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@DS("sqlserver")
@Service
@RequiredArgsConstructor
public class DhgDepartmentServiceImpl extends ServiceImpl<DhgDepartmentMapper, DhgDepartmentEntity> implements DhgDepartmentService {

    private final RedisTemplate<String, Object> redisTemplate;

    private static final String DHG_ROOT_DEPARTMENT = "DHG_ROOT_DEPARTMENT";

    /**
     * 大于等价三级部门的集合
     */
    private static final String DHG_THIRD_LEVEL_LIST = "DHG_THIRD_LEVEL_LIST";


    @Override
    public DhgDepartmentVO getDepartmentTreeByCode(String code) {
        if (StrUtil.isBlank(code)) {
            throw new IllegalArgumentException("部门代码不能为空");
        }
        Boolean hasKey = redisTemplate.hasKey(DHG_THIRD_LEVEL_LIST);

        if (Boolean.FALSE.equals(hasKey)) {
            List<DhgDepartmentEntity> list = this.list();
            DhgDepartmentEntity entity = buildMapAndFillFullTraceStr(list, true);
            Assert.notNull(entity, () -> new IllegalArgumentException("构建部门失败"));
        }
        return (DhgDepartmentVO) redisTemplate.boundHashOps(DHG_THIRD_LEVEL_LIST).get(code);
    }


    /**
     * 构建层级结构并且填充全路径 和大于等于三级部门的路径
     * 返回 根节点
     *
     * @param nodes 节点
     * @return {@link Map }<{@link String }, {@link List }<{@link DhgDepartmentEntity }>>
     */
    public DhgDepartmentEntity buildMapAndFillFullTraceStr(List<DhgDepartmentEntity> nodes, Boolean isCached) {
        Map<BigInteger, DhgDepartmentEntity> nodeMap = nodes.stream().collect(Collectors.toMap(
                DhgDepartmentEntity::getOriginId, item -> item,
                (first, second) -> first)
        );
        DhgDepartmentEntity root = new DhgDepartmentEntity();
        for (DhgDepartmentEntity node : nodes) {
            if (node.getParentOriginId() == null || node.getParentOriginId().equals(BigInteger.ZERO)) {
                node.setFullPathName(node.getName());
                root = node;
            } else {
                DhgDepartmentEntity parentNode = nodeMap.get(node.getParentOriginId());
                if (parentNode != null) {
                    parentNode.getChildren().add(node);
                }

            }
        }
        List<DhgDepartmentVO> higherLevelList = setFullPath(root, root.getName(), new ArrayList<>());

        if (isCached) {
            // 缓存数据
            // 当不存在时候才设置值  存入root的值
            BoundValueOperations<String, Object> keyValueOp = redisTemplate.boundValueOps(DHG_ROOT_DEPARTMENT);
            keyValueOp.setIfAbsent(root, 20, TimeUnit.HOURS);


            // 存入map集合   存入目标数据值
            Map<String, DhgDepartmentVO> map = higherLevelList.stream()
                    .collect(Collectors.toMap(DhgDepartmentVO::getCode, item -> item, (first, second) -> first));
            BoundHashOperations<String, Object, Object> mapOp = redisTemplate.boundHashOps(DHG_THIRD_LEVEL_LIST);
            mapOp.putAll(map);
            mapOp.expire(20,  TimeUnit.HOURS);

        }

        return root;
    }


    /**
     * 设置全路径
     *
     * @param root     根
     * @param basePath 基本路径
     */
    private List<DhgDepartmentVO> setFullPath(DhgDepartmentEntity root, String basePath,List<DhgDepartmentVO> higherLevelList) {
        Opt.ofNullable(root).orElseThrow(() -> new RuntimeException("根节点不能为null"));
        // 递归处理子部门
        List<DhgDepartmentEntity> children = root.getChildren();

        if (children != null && !children.isEmpty()) {
            for (DhgDepartmentEntity child : children) {
                String fullPathStr = basePath + ">" + child.getName().trim();
                child.setFullPathName(fullPathStr);
                if (child.getLevel() >= 3) {
                    // 设置三级路径上名称
                    String str = child.getFullPathName();
                    int firstIndex = str.indexOf(">");
                    int secondIndex = str.indexOf(">", firstIndex + 1);
                    String res = child.getFullPathName().substring(secondIndex + 1);
                    child.setThirdLevePathName(res);

                    //  修改逻辑,减小redis存储内容
                    DhgDepartmentConvertMapper instance = DhgDepartmentConvertMapper.INSTANCE;
                    DhgDepartmentVO vo = instance.convert2VO(child);
                    higherLevelList.add(vo);
                }else{
                    child.setThirdLevePathName("");
                }
                this.setFullPath(child, fullPathStr,higherLevelList);
            }
        }
        return higherLevelList;
    }
}
